package Concurrent;

import sun.misc.Unsafe;

import java.lang.reflect.Field;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 三种方式实现的线程安全的累加
 * 分别为AtomicInteger,Synchronized,CAS
 * Created by wangyg 
 * on 2017/6/14 14:43
 */
public class AtomicIntegerTest {
	private static AtomicInteger count = new AtomicInteger(0);
	private static int n = 0;
	private static int m = 0;
	private static final long valueOffset;

	AtomicIntegerTest() {
	}

	private static AtomicIntegerTest instance = new AtomicIntegerTest();

	public AtomicIntegerTest getInstance() {
		return instance;
	}

	static {
		try {
			valueOffset = getUnsafe().objectFieldOffset
					(AtomicIntegerTest.class.getDeclaredField("value"));
		} catch (Exception ex) {
			throw new Error(ex);
		}
	}

	private volatile int value = 0;

	public synchronized static int IntegerIncreament() {
		try {
			Thread.sleep(200);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		return n++;

	}

	public static Unsafe getUnsafe() {
		Unsafe unsafe = null;
		try {
			Field f = Unsafe.class.getDeclaredField("theUnsafe");
			f.setAccessible(true);
			unsafe = (Unsafe) f.get(null);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return unsafe;
	}

	public int addIntCAS(int m) throws NoSuchFieldException {

		try {
			Thread.sleep(200);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		m = getUnsafe().getAndAddInt(this, valueOffset, 1);

		return m;
	}

	public static int AtomicIntegerIncrement() {
		try {
			Thread.sleep(200);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		int andIncrement = count.getAndIncrement();
		return andIncrement;

	}

	public static void main(String[] args) {
		for (int i = 0; i < 10; i++) {

			new Thread() {
				public void run() {
					System.out.println("Integer值为：" + IntegerIncreament());
					System.out.println("AtomicInteger值为：" + AtomicIntegerIncrement());
					try {
						System.out.println("CAS获取的值为：" + instance.addIntCAS(m));
					} catch (NoSuchFieldException e) {
						e.printStackTrace();
					}

				}
			}.start();
		}
	}

}
